<?php 
/**
 * 生成菜单类
 * 需要一个数据表 menu(id,menu,father,order)
 * @access public
 * @relyon dbClass-数据库类
 * @author jack yang
 * @version:1.1.5
 *方法:setAttr,getAttr,getChMenus,getMenuTree,existsMenu,hasChild,hasChMenuTitle,hasChMenuId
 * $m = new menu(21);
$ch = array('title'=>'调味品');
$m->addChild($ch);
$m->save();
$lastF = 10;
 
$m->getMenuTree('link');

function link($menu){
	
	global $lastF;
	
	if($lastF!=0 && $lastF!= $menu->father){
		echo '&nbsp;&nbsp;';	
	}
	echo "<a href='#'>".$menu->title."</a><br />";
	
	if($lastF==0 || $lastF!= $menu->father){
		$lastF = $menu->father;
	}
}

 */
 	if(!defined('IN_WEB')){
		exit;
	}
	
	class menu extends dataBase{
	
		public $title = '';
		public $father = 0;
		public $id = 0;
		public $morder = 5;
		public $table = 'menu';
		public $layer = 0;
		
		protected $children = array(); //保存新增加的子菜单
		protected $tree = array(); //保存返回的菜单树
		
		/*
		@param $p id或者标题
		*/
		public function __construct($p='',$father=''){
			
			parent::__construct();
			
			if(isset($GLOBALS['menuTable'])){
				$this->table = $GLOBALS['menuTable'];
			}
			if(is_numeric($p)){
				
				$this->id = $p;
				
				if(!$this->existsMenu()){
					return false;
				}
				
				$this->getAttr();
				
			}else if(is_string($p)){
			
				$this->title = $p;
				
			}
						
			
		}
		
		/**
		 * 
		 *  添加一个子类
		 * @param string/array $title 子菜单的标题
		 * @reurtn null
		 */
		public function addChild($title){
			
			
			if(is_array($title) && $title != null){
								
				if(isset($title['title'])){
					
					if(!$this->hasChMenuTitle($title['title'])){
						$this->children[]=$title;
					
					}
				}
				
			}
			
		}
		
		/**
		 *  移除子菜单项
		 * @param string/int $child 菜单项
		 * @param $delCh 是否删除相关子项  true/false
		 * @return true/false
		 */
		public function removeChild($child,$delCh=true){
			
			if(is_string($child)){
					
				if(($m = $this->hasChMenuTitle($child))){

					if($this->id){
						
						if($delCh == true){
						
							$m->getMenuTree('removeChild');
						
						}
						
						return $this->deleteRecordEx($this->table,"father=".$this->id." and title='$child'");
						
					}else{
						
						if($this->children!=null){
						
							foreach($this->children as $key=>$sub){
							
								if($sub == $child){
									
									unset($this->children[$key]);
									break;
									
								}
							}
						}
						
						return false;
					}
					
				}	

				return false;
				
			}else if(is_integer($child)){
			
				if($this->id){
					
					if(($m = $this->hasChMenuId($child))){
						if($delCh == true){
						
							$m->getMenuTree('removeChild');
						
						}					
						return $this->deleteRecordEx($this->table,"father=".$this->id." and id='$child'");
					}
					
				}
				
				return false;
			
			}else if(is_object($child)){
			
				
				$this->removeChild($child->id);
			
			}
			
		}
		
		/**
		 * 是否存在菜单项
		 * @param $id 指定id
		 * @return true/false;
		 */
		public function existsMenu($id=''){
			
			if($id!=''){
				
				return $this->recordCount("select id from ".$this->table." where id='".$id."' limit 1");
			
			}else{
			
				if($this->id){
				
					return $this->recordCount('select id from '.$this->table.' where id='.$this->id.' limit 1');
					
				}else{
					
					return false;
				}
				
			}
				
				
		
		}
		
		public function hasChMenuTitle($title){
		
			if($title==''){
			
				return false;
				
			}
			
			if($this->id){
				
					$m = $this->getResultArray("select id from ".$this->table." where title='$title' 
					and father =".$this->id.' limit 1',true);
					
					if($m == null){
						return false;
					}
					return new menu(intval($m['id']));
			
			}else{
			
				if(in_array($title,$this->children)){
				
					return new menu($m['title']);
					
				}
				
				return false;
			}
			
		}
		
		
		public function hasChMenuId($id,$isAll=false){

			if($this->id){
				
				if($isAll == true){
					
					
				
				}
				$m = $this->getResultArray("select id from ".$this->table." where id='$id' 
				and father=".$this->id.' limit 1',true);
				
				
				if($m == null){
					return false;
				}
				return new menu(intval($m['id']));
								
			}else{
			
				return false;
			}
		
		
		}
		
		
		public function hasChild(){
			
			if($this->id){
			
				return $this->recordCount("select id from ".$this->table." where
				father=".$this->id.' limit 1');
			
			}
			
			return false;
			
		}
		
		/*
		获取指定父类的菜单树
		@param $callback回调函数
		*/
		public function getMenuTree($callback=''){
		
			if($this->id ){
				
				$subM = $this->getChMenus();
				
				if($subM != null){
				
					foreach($subM as $key=>$m){
					
						if($callback!='' && function_exists($callback)){
							
							$callback($m);
							
						}else if($callback!='' && method_exists($this,$callback)){
							
							$this->$callback($m);
						}

						
						$this->tree[$m->id] = array(
							'id'=>$m->id,
							'title'=>$m->title,
							'father'=>$m->father,
							'order'=>$m->order,
							
						);
						
						if($m->hasChild()){
						
							$chM = $m->getMenuTree($callback);
							
							if(is_array($chM)){
							
								$this->tree[$m->id]['child'] =  $chM;
								
							}
							
						}
						
					
					}
					

					return $this->tree;
					
				}else{
					

					
					return null;
					
				}
				
			}else{
				
				if($callback!='' && function_exists($callback)){
					
					$callback($this->children);
					
				}else if($callback!='' && method_exists($this,$callback)){
					
					$this->$callback($this->children);
				}			
				return $this->children;
				
			}
		
		}
		
		/**
		 *  判定菜单是否在菜单树中
		 * @param int id 子菜单id;
		 * @return true/false
		 */	
		public function treeHasCh($id){

			if(!$this->existsMenu($id)){
			
				return 0;
				
			}
			
			
			$m = new menu($id);
			
			if($m->father!=$this->id){
				
				if($m->father!=null){
				
					return $this->treeHasCh($m->father);
					
				}
				
				return 0;
				
				
			}else{
			
				return 1;
				
			}
			
			return 0;
				
			
		}	
		
		
		/*
		获取第一层子菜单
		*/
		public function getChMenus(){
		
			if($this->id){

				$sql = "select id from ".$this->table." where father=$this->id order by `morder` asc";
				$sub = $this->getResultArray($sql);

				if($sub!=null){
					
					$subMenu = array();
					foreach($sub as $key=>$each){
						
						$subM = new menu(intval($each['id']),$each['father']);
						$subMenu[] = $subM;
						
					}
					
					return $subMenu;
				}
				
			}else{
				
				if($this->children!=null){
					$subMenu = array();
					foreach($this->children as $key=>$each){
					
						$subM = new menu($each);
						$subMenu[] = $subM;
						
					}
					
					return $subMenu;
					
				}else{
					
					return null;
					
				}
			
			}
		
		}
		
		
		/*
		获取第一层个数
		*/
		public function getSubMenuSum(){
			
			if($this->id){

				$sql = "select count(*) as resum from ".$this->table." where father=$this->id order by `morder` asc";
				$num = $this->recordSum($sql);
				
				return $num;
			
			}
			
			return false;
			
		}
		

		
		/**
		 *  保存菜单
		 * @
		 */
		public function save($other=null){
			
			$menuData = array();
			$menuData['title']   = $this->title;
			$menuData['morder'] = $this->order;
			$this->assignFather($father);
			
			$attrs = $this->getTableFields($this->table);
			
			if(($other = stripNotMatch($other,$attrs))!=null){
				
				$menuData = array_merge($menuData,$other);
			}
			
			if($this->id && !$this->existsMenu()){
				
				$this->errorStr('指定的菜单不存在,id:'.$this->id.'不存在!');
				
				return false;
				
			}
			
			if($this->father){
				
				$menuData['father'] = $this->father;
					
			}
			
			if($this->title=='' && $this->id == 0){
			
					$this->errorStr('菜单文本不能为空!');					
					return false;
			}
			
			
			if($this->id){

				$this->updateRecord($this->table,$menuData,"id=".$this->id);
				$id = $this->id;
				
			}else{
				if($this->title == ''){
				
					echo '菜单文本不能为空!';
					return false;
					
				}
				
				
				if($this->father){
					
					$f = new menu($this->father);
					if($f->hasChMenuTitle($this->title)){
					
						$this->errorStr('菜单文本重复!');
						return false;
					}
				
				}
				
				
				$this->insertRecordEx($this->table,$menuData);
				$sql = 'select max(id) as lid from '.$this->table.' limit 1 for update';
				$temp = $this->getResultArray($sql,true);
				
				$id = $temp['lid'];
				
				$this->id = $id;

			}
			
			
			if($this->children != null){
			
				
				$order = count($this->getChMenus())+1;
				
				foreach($this->children as $key=>$sub){
					
					$subData = array();
					$subData['father'] = $id;
					$subData['morder'] = $order;
					unset($sub['father']);
					
					foreach($sub as $k=>$s){
						
						if(in_array($k,$attrs)){
							$subData[$k] = $s;	
						}
					}
					
					$this->insertRecordEx($this->table,$subData);
					$order++;
				
				}
			
			}
			
				
			return true;
		}		
		
		protected function assignFather($father){
			
			if($father!=0){
				
				if(!$this->existsMenu($father)){
				
					die('指定的父类不存在!');
					
				}

							
				if( $this->father == $this->id ){
					
					$this->errorStr('父菜单不能是自己!');
					die();
				
				}
				
				if($this->hasChMenuId($this->father) || $this->treeHasCh($this->father)){
				
					$this->errorStr('父菜单不能是子菜单!');
					die();
				
				}
				
				if(!$this->existsMenu($this->father)){
				
					die('指定的父类不存在!');
					return false;
				}
				
				$this->father = $father;
			}
		
		}
		
		/*
		异常报告
		*/
		protected function errorStr($exception){	
			
			if(class_exists('error') && is_object($GLOBALS['error'])){			
				$GLOBALS['error']->showErrorStr($exception,'javascript:',false);
			}else{
				throw new Exception($exception);
			}
		}
		

		
		/*
		获取相关属性
		*/
		public function getAttr($attr=''){
		
			if(!$this->id ){
				return false;
			}
			
			
			$id = $this->id;
			$sql = "select*from ".$this->table." where id='$id' limit 1";
			$menu = $this->getResultArray($sql,true);
			if($attr!=''){
				return $menu[$attr];
			}
			
			if($menu!=null){	
				foreach($menu as $att=>$val){
					$this->$att = $val;	
				}
			}
			
			return $menu;
		}
		
		/*
		更新相关属性
		*/
		public function setAttr($attr,$newVal){
		
			if(!$this->existsMenu()){
				return false;
			}
			
			if($attrs == 'id'){
				return false;
			}
			
			$attrs = $this->getTableFields($this->table);
			if($attr!='title' && !in_array($attr,$attrs)){
				$this->errorStr('属性不存在!');
				return false;
			}
			
			
			return $this->update($this->table,array($attr=>$newVal),"id=".$this->id);
			
		}
	}

?>